﻿#If NETFX_CORE Then
Imports Windows.Storage
Imports Runa.Common.Helper
Imports Runa.Common.Helper.Text
Imports System.Reflection
Imports System.Runtime.ExceptionServices
Imports System.Runtime.CompilerServices
Imports System.Runtime.Serialization
Imports System.Runtime.InteropServices
Imports System.Runtime.InteropServices.WindowsRuntime

Namespace Global.System.IO.IsolatedStorage

    Public Enum FileMode
        Append = 6
        Create = 2
        CreateNew = 1
        Open = 3
        OpenOrCreate = 4
        Truncate = 5
    End Enum

    Public Class IsolatedStorageFile

        Public Property PhysicalLocation() As StorageFolder

        Public Sub New()
            Me.PhysicalLocation = ApplicationData.Current.LocalFolder
        End Sub

        Public Sub New(ByVal path As String)
            Me.PhysicalLocation = StorageFolder.GetFolderFromPathAsync(path).AsTask().Result
        End Sub

        Public Function OpenFile(ByVal fileName As String, ByVal fileMode As FileMode, Optional ByVal accessMode As FileAccess = FileAccess.ReadWrite) As Stream
            Dim fa As FileAccessMode = If(accessMode = FileAccess.ReadWrite Or accessMode = FileAccess.Write, FileAccessMode.ReadWrite, FileAccessMode.Read)
            Dim item As Global.Windows.Storage.IStorageFile = Nothing
            Select Case fileMode
                Case IsolatedStorage.FileMode.Create
                    item = Me.PhysicalLocation.CreateFileAsync(fileName, CreationCollisionOption.FailIfExists).AsTask().Result
                    Return item.OpenAsync(fa).AsTask().Result.AsStream()
                Case IsolatedStorage.FileMode.CreateNew
                    item = Me.PhysicalLocation.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting).AsTask().Result
                    Return item.OpenAsync(fa).AsTask().Result.AsStream()
                Case IsolatedStorage.FileMode.Open
                    item = Me.PhysicalLocation.GetFileAsync(fileName).AsTask().Result
                    Return item.OpenAsync(fa).AsTask().Result.AsStream()
                Case IsolatedStorage.FileMode.OpenOrCreate
                    item = Me.PhysicalLocation.CreateFileAsync(fileName, CreationCollisionOption.OpenIfExists).AsTask().Result
                    Return item.OpenAsync(fa).AsTask().Result.AsStream()
                Case IsolatedStorage.FileMode.Append
                    item = Me.PhysicalLocation.GetFileAsync(fileName).AsTask().Result
                    Dim ret = item.OpenAsync(fa).AsTask().Result.AsStream()
                    ret.Seek(0, SeekOrigin.End)
                    Return ret
                Case Else
                    item = Me.PhysicalLocation.CreateFileAsync(fileName, CreationCollisionOption.OpenIfExists).AsTask().Result
                    Return item.OpenAsync(fa).AsTask().Result.AsStream()
            End Select
        End Function

        Public Function FileExists(ByVal fileName As String) As Boolean
            Dim items = Me.PhysicalLocation.GetFilesAsync().AsTask().Result
            Return (From item In items Where item.Name.ToLower() = fileName.ToLower() Select item).Count() = 1
        End Function

        Public Function DirectoryExists(ByVal dirName As String) As Boolean
            Dim items = Me.PhysicalLocation.GetFoldersAsync().AsTask().Result
            Return (From item In items Where item.Name.ToLower() = dirName.ToLower() Select item).Count() = 1
        End Function

        Public Sub DeleteDirectory(ByVal fileName As String)
            Me.PhysicalLocation.GetFolderAsync(fileName).AsTask().Result.DeleteAsync().AsTask().StartSynchronously()
        End Sub

        Public Sub DeleteDirectory(ByVal fileName As String, ByVal isSearchSubFolders As Boolean)
            Me.PhysicalLocation.GetFolderAsync(fileName).AsTask().Result.DeleteAsync().AsTask().StartSynchronously()
        End Sub

        Public Sub CreateDirectory(ByVal dirName As String)
            Me.PhysicalLocation.CreateFolderAsync(dirName).AsTask().StartSynchronously()
        End Sub

        Public Function GetDirectory(ByVal dirName As String) As IStorageFolder
            Return Me.PhysicalLocation.GetItemAsync(dirName).AsTask().Result
        End Function

        Public Function GetFileNames(ByVal filter As String) As String()
            Return (From item In Me.PhysicalLocation.GetFilesAsync().AsTask().Result Where MatchRegx(item.Name, filter) Select item.Name).ToArray()
        End Function

        Public Function GetDirectoryNames(ByVal filter As String) As String()
            Return (From item In Me.PhysicalLocation.GetFoldersAsync().AsTask().Result Where MatchRegx(item.Name, filter) Select item.Name).ToArray()
        End Function

        Public Function GetFileNames(ByVal filter As Func(Of String, Boolean)) As String()
            Return (From item In Me.PhysicalLocation.GetFilesAsync().AsTask().Result Where filter(item.Name) Select item.Name).ToArray()
        End Function

        Public Function GetDirectoryNames(ByVal filter As Func(Of String, Boolean)) As String()
            Return (From item In Me.PhysicalLocation.GetFoldersAsync().AsTask().Result Where filter(item.Name) Select item.Name).ToArray()
        End Function

        Public Sub DeleteFile(ByVal fileName As String)
            Me.PhysicalLocation.GetFileAsync(fileName).AsTask().Result.DeleteAsync().AsTask().StartSynchronously()
        End Sub

        Public Shared Function GetUserStoreForAssembly() As IsolatedStorageFile
            Return New IsolatedStorageFile()
        End Function

        Public Shared Function GetUserStoreForApplication() As IsolatedStorageFile
            Return New IsolatedStorageFile()
        End Function

    End Class

End Namespace

#End If